#pragma once

/*
IO16    负载输出控制
IO32    EG2104的IN
IO33    EG2104的SD
IO34    NTC热敏电阻
*/
#define NTC_PIN 34 // PCB温度检测
#define PWM_PIN 32
#define PWM_ENABLE_PIN 33
#define LOAD_PIN 16

/*PWM*/
#define pwmChannel 0       // LEDC通道
#define pwmFrequency 39000 // PWM频率39KHz
#define pwmResolution 11   // PWM分辨率

#define PWM_start 1842 // 90%的占空比
const int PWM_MAX = 2047;
int PWM = 0; // 系统工作时输出的PWM，0~2047，转化为 % = PWM*100/2047

byte PWM_delta = 1;

/*光伏电池和铅酸电池初值设置*/
#define LOW_SOL_WATTS 5.00 // 光伏电池最小工作功率
#define MIN_SOL_WATTS 1.00

#define MIN_bat_voltsS 11.00 // 铅酸电池的最小工作电压
#define MAX_bat_voltsS 14.10 // 铅酸电池的满电电压
#define BATT_FLOAT 13.60     // 铅酸电池的浮充电压

#define OFF_NUM 9

float old_Solar_P = 0.0;
int pct = 0;              // 铅酸电池电量
bool load_status = false; // 初始负载状态

/*EG2104工作状态控制*/
#define TURN_ON_MOSFETS digitalWrite(PWM_ENABLE_PIN, HIGH)
#define TURN_OFF_MOSFETS digitalWrite(PWM_ENABLE_PIN, LOW)

typedef struct
{
  volatile float tempC;
  volatile float Solar_V;
  volatile float Solar_I;
  volatile float Solar_P;

  volatile float Charge_V;
  volatile float Charge_I;
  volatile float Charge_P;
} SensorData;
SensorData data = {0};

enum charger_mode // 充电模式
{
  off,
  on,
  bulk,
  bat_float
} charger_state;

void run_charger()
{
  static int off_count = OFF_NUM;
  switch (charger_state)
  {
  case off:
    TURN_OFF_MOSFETS;
    if (off_count > 0)
    {
      off_count--;
    }
    else if ((data.Charge_V > BATT_FLOAT) && (data.Solar_V > data.Charge_V))
    {
      charger_state = bat_float;
      TURN_ON_MOSFETS;
    }
    else if ((data.Charge_V > MIN_bat_voltsS) && (data.Charge_V < BATT_FLOAT) && (data.Solar_V > data.Charge_V))
    {
      charger_state = bulk;
      TURN_ON_MOSFETS;
    }
    break;

  case on:
    if (data.Solar_P < MIN_SOL_WATTS)
    {
      charger_state = off;
      off_count = OFF_NUM;
      TURN_OFF_MOSFETS;
    }
    else if (data.Charge_V > (BATT_FLOAT - 0.1))
    {
      charger_state = bat_float;
    }
    else if (data.Solar_P < LOW_SOL_WATTS)
    {
      PWM = PWM_MAX;
      ledcWrite(pwmChannel, PWM);
    }
    else // (data.Solar_P > LOW_SOL_WATTS) && (data.Charge_V < BATT_FLOAT)
    {
      PWM = (((data.Charge_V * 10) / (data.Solar_V / 10)) + 5) * 20.47;
      charger_state = bulk;
    }
    break;

  case bulk:
    if (data.Solar_P < MIN_SOL_WATTS)
    {
      charger_state = off;
      off_count = OFF_NUM;
      TURN_OFF_MOSFETS;
    }
    else if (data.Charge_V > BATT_FLOAT)
    {
      charger_state = bat_float;
    }
    else if (data.Solar_P < LOW_SOL_WATTS)
    {
      charger_state = on;
      TURN_ON_MOSFETS;
    }
    else
    {
      if (old_Solar_P >= data.Solar_P) // 当前工作在最大功率点右侧
      {
        PWM_delta = -PWM_delta;
      }
      PWM += PWM_delta;
      old_Solar_P = data.Solar_P;
      ledcWrite(pwmChannel, PWM);
    }
    break;

  case bat_float:
    if (data.Solar_P < MIN_SOL_WATTS)
    {
      charger_state = off;
      off_count = OFF_NUM;
      TURN_OFF_MOSFETS;
      ledcWrite(pwmChannel, PWM);
    }
    else if (data.Charge_V > BATT_FLOAT)
    {
      PWM = PWM_MAX;
      ledcWrite(pwmChannel, PWM);
      TURN_OFF_MOSFETS;
    }
    else if (data.Charge_V < BATT_FLOAT)
    {
      PWM = PWM_MAX;
      ledcWrite(pwmChannel, PWM);
      TURN_ON_MOSFETS;
      if (data.Charge_V > (BATT_FLOAT - 0.1))
      {
        charger_state = bulk;
      }
    }
    break;

  default:
    TURN_OFF_MOSFETS;
    break;
  }
}
